package com.lee.demonacosclient.configuration;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName NacosClusterWeightRule
 * @Description 支持 nacos的相同集群节点优先调用
 * @Author leejiliang
 * @DateTime 2020/9/20 8:23 AM
 * @Version 1.0
 */
public class NacosClusterWeightRule extends AbstractLoadBalancerRule {
	@Autowired
	private NacosDiscoveryProperties nacosDiscoveryProperties;
	@Autowired
	private NacosServiceManager nacosServiceManager;
	@Override
	public void initWithNiwsConfig(IClientConfig iClientConfig) {

	}

	@Override
	public Server choose(Object o) {

		String clusterName = nacosDiscoveryProperties.getClusterName();
		BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
		String name = loadBalancer.getName();
		NamingService namingService = nacosServiceManager.getNamingService(nacosDiscoveryProperties.getNacosProperties());

		try {
			//找到所有的健康实例
			List<Instance> instances = namingService.selectInstances(name, true);
			List<Instance> sameClusterNodes = instances.stream().filter(i -> clusterName.equals(i.getClusterName())).collect(Collectors.toList());
			if (CollectionUtils.isEmpty(sameClusterNodes)) {
				sameClusterNodes = instances;
			}
			Instance oneInstance = CustomerLoadBalancer.getOneInstance(sameClusterNodes);
			return new NacosServer(oneInstance);
		} catch (NacosException e) {
			e.printStackTrace();
		}
		return null;
	}
}

class CustomerLoadBalancer extends Balancer{
	public static Instance getOneInstance(List<Instance> instances) {
		return getHostByRandomWeight(instances);
	}
}
